package com.tanhua.server.service;

import com.tanhua.commons.exception.TanHuaException;
import com.tanhua.commons.templates.OssTemplate;
import com.tanhua.manage.domain.db.UserInfo;
import com.tanhua.manage.domain.mongo.Publish;
import com.tanhua.manage.domain.mongo.Visitor;
import com.tanhua.manage.domain.vo.MomentVo;
import com.tanhua.manage.domain.vo.PageResult;
import com.tanhua.manage.domain.vo.PublishVo;
import com.tanhua.manage.domain.vo.VisitorVo;
import com.tanhua.dubbo.api.PublishApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VisitorApi;
import com.tanhua.server.interceptor.UserHolder;
import com.tanhua.server.utils.RelativeDateFormat;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.dubbo.common.utils.CollectionUtils;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MomentService {

    @Reference
    private PublishApi publishApi;
    @Autowired
    private OssTemplate ossTemplate;
    @Reference
    private UserInfoApi userInfoApi;
    @Autowired
    private RedisTemplate redisTemplate;
    @Reference
    private VisitorApi visitorApi;

    /**
     * 发布动态
     * @return
     */
    public void postMoment(PublishVo publishVo, MultipartFile[] imageContent) {
        Long userId = UserHolder.getUserId();

        List<String> medias = new ArrayList<>();
        if (null!=imageContent) {
            try {
                for (MultipartFile image : imageContent) {
                    String imageUrl = ossTemplate.upload(image.getOriginalFilename(), image.getInputStream());
                    medias.add(imageUrl);
                }
            } catch (IOException e) {
                log.error("上传图片失败",e);
                throw new TanHuaException("上传图片失败");
            }
        }
        Publish publish = new Publish();
        BeanUtils.copyProperties(publishVo,publish);

        publish.setUserId(userId);
        publish.setState(0);
        publish.setMedias(medias);
        publish.setSeeType(1);
        publish.setLocationName(publishVo.getLocation());

        publishApi.add(publish);
    }

    /**
     * 好友 动态
     * @param page
     * @param pageSize
     * @return
     */
    public PageResult<MomentVo> queryFriendPublishList(Long page, Long pageSize) {
        Long userId = UserHolder.getUserId();
        PageResult pageResult = publishApi.findFriendPublishByTimeline(userId,page,pageSize);
        List<Publish> publishList = pageResult.getItems();

        //构建List vo
        List<MomentVo> voList = new ArrayList<MomentVo>();
        if (!CollectionUtils.isEmpty(publishList)) {
            for (Publish publish : publishList) {
                Long publishUserId = publish.getUserId();
                UserInfo userInfo = userInfoApi.findById(publishUserId);

                // 复制用户详情
                MomentVo vo = new MomentVo();
                BeanUtils.copyProperties(userInfo,vo);
                vo.setTags(StringUtils.split(userInfo.getTags(),","));
                // 复制动态的信息
                BeanUtils.copyProperties(publish,vo);
                //设置补充vo属性
                vo.setImageContent(publish.getMedias().toArray(new String[]{}));
                vo.setDistance("100米");
                vo.setCreateDate(publish.getCreated().toString());
                vo.setId(publish.getId().toString());
                vo.setHasLiked(0);
                String key = "publish_like_"+UserHolder.getUserId()+"_"+vo.getId();
                if (redisTemplate.hasKey(key)){
                    vo.setHasLiked(1);
                }
                vo.setHasLoved(0);

                vo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCommentCount())));

                voList.add(vo);

            }

        }
        pageResult.setItems(voList);
        return pageResult;
    }

    /**
     * 方法2 好友动态
     */
    public PageResult<MomentVo> queryFriendPublishList2(Long page, Long pageSize) {

        Long loginUserId = UserHolder.getUserId();
        PageResult pageResult = publishApi.findFriendPublishByTimeline(loginUserId,page,pageSize);

        List<Publish> publishList = pageResult.getItems();

        if (!CollectionUtils.isEmpty(publishList)){
            List<Long> userIds = publishList.stream().map(Publish::getUserId).collect(Collectors.toList());
            List<UserInfo> userInfoList = userInfoApi.findByBatchId(userIds);
            Map<Long, UserInfo> userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfo::getId, v -> v));

            List<MomentVo> voList = publishList.stream().map(publish -> {
                MomentVo vo = new MomentVo();
                BeanUtils.copyProperties(publish, vo);
                vo.setImageContent(publish.getMedias().toArray(new String[]{}));
                vo.setDistance("100米");
                vo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));

                UserInfo userInfo = userInfoMap.get(publish.getUserId());
                BeanUtils.copyProperties(userInfo, vo);
                vo.setTags(StringUtils.split(userInfo.getTags(), ","));
                vo.setId(publish.getId().toHexString());
                vo.setHasLiked(0);
                String key = "publish_like_"+UserHolder.getUserId()+"_"+vo.getId();
                if (redisTemplate.hasKey(key)){
                    vo.setHasLiked(1);
                }
                return vo;
            }).collect(Collectors.toList());

            pageResult.setItems(voList);


        }
        return pageResult;
    }

    /**
     * 查询推荐动态
     * @param page
     * @param pageSize
     * @return
     */
    public PageResult<MomentVo> queryRecommendPublishList(Long page, Long pageSize) {
        Long loginUserId = UserHolder.getUserId();
        PageResult pageResult = publishApi.findRecommendPublishByTimeline(loginUserId,page,pageSize);
        List<Publish> publishList = pageResult.getItems();
        //List<ObjectId> publishIds = publishList.stream().map(Publish::getId).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(publishList)){
            //取出所有作者ids
            List<Long> userIds = publishList.stream().map(Publish::getUserId).collect(Collectors.toList());
            List<UserInfo> userInfoList = userInfoApi.findByBatchId(userIds);
            //把作者是信息转成map<Key=作者id, value=作者userInfo>
            Map<Long, UserInfo> userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfo::getId, u -> u));
            //把动态转成momentvo
            List<MomentVo> voList = publishList.stream().map(publish -> {
                MomentVo vo = new MomentVo();
                BeanUtils.copyProperties(publish, vo);

                if (null!=publish.getMedias()) {
                    vo.setImageContent(publish.getMedias().toArray(new String[]{}));
                }

                vo.setDistance("100米");
                vo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));

                UserInfo userInfo = userInfoMap.get(publish.getUserId());
                BeanUtils.copyProperties(userInfo, vo);
                vo.setTags(StringUtils.split(userInfo.getTags(),","));
                vo.setId(publish.getId().toHexString());
                vo.setHasLiked(0);
                String key = "publish_like_"+UserHolder.getUserId()+"_"+vo.getId();
                if (redisTemplate.hasKey(key)){
                    vo.setHasLiked(1);
                }

                return vo;
            }).collect(Collectors.toList());


            pageResult.setItems(voList);
        }

        return pageResult;
    }

    /**
     * 查询我的动态
     */
    public PageResult<MomentVo> queryMyPublishList(Long userId,Long page, Long pageSize) {

        //先获取用户信息
        Long loginUserId = UserHolder.getUserId();
        Long targetUserId = loginUserId;
        if(null != userId){
            // 如果 userId有值，查看某个用户的所有动态
            targetUserId = userId;
        }
        //查询用户自己的时间表，获取publish集合
        PageResult pageResult = publishApi.findMyPublishListByTimeLine(targetUserId,page,pageSize);
        List<Publish> publishList = pageResult.getItems();

        //获取userInfo
        UserInfo userInfo = userInfoApi.findById(targetUserId);
        if (!CollectionUtils.isEmpty(publishList)){
            //转momentVo
            List<MomentVo> voList = publishList.stream().map(publish -> {
                MomentVo vo = new MomentVo();
                BeanUtils.copyProperties(publish, vo);
                vo.setImageContent(publish.getMedias().toArray(new String[]{}));
                BeanUtils.copyProperties(userInfo, vo);
                vo.setTags(StringUtils.split(userInfo.getTags(), ","));
                vo.setId(publish.getId().toHexString());
                vo.setDistance("100米");
                vo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));

                return vo;
            }).collect(Collectors.toList());
            //包装成pageresult返回
            pageResult.setItems(voList);
        }
        return pageResult;
    }
    /**
     * 查询单条动态
     */
    public MomentVo findById(String publishId) {
        //Long userId = UserHolder.getUserId();
        Publish publish = publishApi.findById(publishId);
        MomentVo vo = new MomentVo();
        UserInfo userInfo = userInfoApi.findById(publish.getUserId());
        BeanUtils.copyProperties(userInfo,vo);
        vo.setTags(StringUtils.split(userInfo.getTags(),","));
        BeanUtils.copyProperties(publish,vo);
        vo.setImageContent(publish.getMedias().toArray(new String[]{}));
        vo.setDistance("100米");
        vo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
        vo.setId(publish.getId().toHexString());

        //是否点过赞
        vo.setHasLiked(0);
        String key = "publish_like_" + UserHolder.getUser()+"_" + vo.getId();
        if (redisTemplate.hasKey(key)){
            vo.setHasLiked(1);
        }
        //是否喜欢
        vo.setHasLoved(0);
        key = "publish_love_" + UserHolder.getUser()+"_" + vo.getId();
        if (redisTemplate.hasKey(key)){
            vo.setHasLoved(1);
        }

        return vo;

    }

    /**
     * 谁看过我
     */
    public List<VisitorVo> queryVisitors() {
        //1. 取出redis中设置上次查询时间
        String key = "visitors_time_" + UserHolder.getUserId();
        Long lastQueryTime = (Long) redisTemplate.opsForValue().get(key);

        //2. 如果存在, 按时间条件查询前4条访客
        //3. 不存在，按时间降序取前4条访客
        List<Visitor> visitors = visitorApi.queryLast4Visitors(UserHolder.getUserId(),lastQueryTime);
        List<VisitorVo> voList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(visitors)) {
            //取出所有访客的ID
            List<Long> visitorsIds = visitors.stream().map(Visitor::getVisitorUserId).collect(Collectors.toList());
            //获取到访客的info信息
            Map<Long, UserInfo> userInfoMap = userInfoApi.findByBatchId(visitorsIds).stream().collect(Collectors.toMap(UserInfo::getId, u -> u));
            //转vo
            voList = visitors.stream().map(visitor -> {
                VisitorVo vo = new VisitorVo();
                Long visitorUserId = visitor.getVisitorUserId();
                vo.setId(visitorUserId);
                UserInfo userInfo = userInfoMap.get(visitorUserId);
                BeanUtils.copyProperties(userInfo, vo);
                vo.setTags(StringUtils.split(userInfo.getTags(), ","));
                if (null == visitor.getScore()) {
                    vo.setFateValue(RandomUtils.nextInt(70, 80));
                } else {
                    vo.setFateValue(visitor.getScore().intValue());
                }
                return vo;
            }).collect(Collectors.toList());

        }

        return voList;
    }
}
